<?php
namespace libraries\common;

defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Checking Status Trait
 *
 * @desc    基于状态位的审核, 提供审核的快捷方法
 * @version 1.0.0
 * @author  Jason
 * @date	2017年6月20日 下午12:05:32
 */
trait CheckingStatus
{
	/**
	 * 状态之审核：审核通过和未通过
	 *
	 * @desc    审核通过和未通过
	 * @author  Jason
	 * @date	2017年6月20日 上午11:31:11
	 * 
	 * @version	1.1.0
	 * @date	2017年6月20日 下午3:05:54
	 * @desc	清晰职责
	 * 
	 * @param   string $mapping 表映射，代码调用传参数(非表单参数)
	 * 
	 * @param   number $id			ID
	 * @param   string $judgement	通过还是不通过，accepted/rejected，默认拒绝
	 * @param   string $comment		通过备注，不通过原因
	 * @param   string $module		模块名称，要审核的数据模型名称
	 *
	 * @return [<status>, <content>]	一个两元素数组，第一个元素表示状态，第二个表示相应内容
	 * 	        eg:	[true, ['nowTag' => 'enabled']]
	 * 				[true, ['nowTag' => 'disabled']]
	 * 				[false, ['error']]
	 */
	public function change_checking_status($mapping = 'master')
	{
		$component = str_replace('Lib_', '', get_class());
		$component_mapping = (is_string($mapping) && $mapping !== 'master') ? "{$component}_{$mapping}" : $component;
		
		// $id, $judgement = 'accepted', $comment = '', $module = 'merchant'
		$id = $this->CI->input->post('id');
		$judgement = $this->CI->input->post('judgement') ? : 'rejected';
		$comment = $this->CI->input->post('comment') ? : '';
		$module = $this->CI->input->post('module') ? : $component_mapping;
		
		list($status, $content) = $this->do_change_checking_status($id, $judgement, $comment, $module, $mapping);
		
		return [$status, $content];
	}
	
	/**
	 * 状态之审核：执行审核通过和未通过
	 *
	 * @desc    执行审核通过和未通过
	 * @author  Jason
	 * @date	2017年6月20日 上午11:31:11
	 * 
	 * @version	1.1.0
	 * @date	2017年6月20日 下午3:05:54
	 * @desc	清晰条理
	 * 
	 * @param   number $id			ID
	 * @param   string $judgement	通过还是不通过，accepted/rejected，默认拒绝
	 * @param   string $comment		通过备注，不通过原因
	 * @param   string $module		模块名称，要审核的数据模型名称
	 * @param   string $mapping		表映射，代码调用传参数
	 *
	 * @return [<status>, <content>]	一个两元素数组，第一个元素表示状态，第二个表示相应内容
	 * 	        eg:	[true, ['nowTag' => 'enabled']]
	 * 				[true, ['nowTag' => 'disabled']]
	 * 				[false, ['error']]
	 */
	protected function do_change_checking_status($id, $judgement = 'accepted', $comment = '', $module = 'merchant', $mapping = 'master')
	{
		$component = str_replace('Lib_', '', get_class());
		
		// 初始化返回值
		$status = true;
		$content = [];
		
		// 获取状态位十进制数
		if ($status) {
			// function is_exists(){};
			// 获取数据库中保存的状态位数字
			$status_dec = $this->{"mod_$component"}->select_status($id, $mapping);
			if (is_null($status_dec)) {
				$status = false;
				$content[] = 'common_msg_not_found';
			}
		}
		
		// 验证审核开关
		if ($status) {
			// function is_oncheck(){};
			$status_tags = $this->{"mod_$component"}->calculate_status_tags($status_dec, 'positive', $mapping);
			if (in_array('check_over', $status_tags)) {
				$status = false;
				$content[] = 'status_checking_msg_can_not_repeat_operation';
			}
		}
		
		// 关闭审核开关
		if ($status) {
			$status = $this->{"mod_$component"}->mark_status_by_tag($id, 'check_over', $mapping);
			$status or $content[] = 'status_checking_msg_can_not_repeat_operation';
		}
		
		// 应该是开关阻断状态！！
		if ($status) {
			// 审核通过和未通过
			if ($judgement == 'accepted') {
				# $oper_status = 不能加这个阻断条件！
				// 因为虽然状态为审核中，但是被阻断的审核状态总是有一个值，或者通过或者未通过。
				// 所以上面这个阻断恰好把关系搞反了：应该是开关阻断状态！！
				$this->{"mod_$component"}->mark_status_by_tag($id, 'checked', $mapping);
			} else {
				# $oper_status = 
				$this->{"mod_$component"}->unmark_status_by_tag($id, 'checked', $mapping);
			}
		}
		
		// 记录日志
		if ($status) {
			$status_dec = ($judgement == 'accepted') ? '1' : '0';
			$member_id = $this->CI->get_logined_member()['id'];
			$this->CI->load->model('mod_check');
			$status = $this->CI->mod_check->set_last($module, $id, $status_dec, $comment, $member_id);
			$status or $content[] = 'status_checking_msg_error_occurred_while_logging';
		}
		
		return [$status, $content];
	}
	
	/**
	 * 状态之进入审核流程
	 *
	 * @desc    将审核开关打开
	 * @author  Jason
	 * @date	2017年6月20日 下午12:40:48
	 *
	 * @param   number $id		ID
	 * @param   string $mapping	表映射，代码调用传参数
	 *
	 * @return [<status>, <content>]	一个两元素数组，第一个元素表示状态，第二个表示相应内容
	 * 	        eg:	[true, ['nowTag' => 'enabled']]
	 * 				[true, ['nowTag' => 'disabled']]
	 * 				[false, ['error']]
	 */
	public function open_checking_switch_status($id, $mapping = 'master')
	{
		$component = str_replace('Lib_', '', get_class());
		
		// 审核中...
		$oper_status = $this->{"mod_$component"}->unmark_status_by_tag($id, 'check_over', $mapping);
		
		return $oper_status;
	}
	
	
	/**
	 * 审核状态标签校准：如果正在审核中，忽略之前是否审核通过的状态。
	 * 
	 * @desc	如果正在审核中，忽略之前是否审核通过的状态。
	 * 			只有审核完毕，审核状态才生效的！
	 * 			同时直接正向标签和负向标签！
	 * @desc	审核中去除审核结果，状态判断时：没完毕就是审核中 & 没通过就是未通过。
	 * @version	1.0.0
	 * @author	Jason
	 * @date	2017年7月28日 上午10:40:17
	 * 
	 * @param   array  $tags 		状态字符串标签数组, 支持正向标签和负向标签，注意要与传递的第二个参数匹配！
	 * @param	string $attitude	positive/negative !negative => positive
	 *
	 * @return	array
	 */
	protected function filter_checking_status($tags, $attitude = 'positive')
	{
		$attitude = in_array($attitude, ['positive', 'negative']) ? $attitude : 'positive';
		
		// 正向标签，尚未审核完毕
		if ($attitude == 'positive' && !in_array('check_over', $tags)) {
			$key = array_search('checked', $tags);
			// if ($key !== FALSE) unset($tags[$key]);
			// http://www.jb51.net/article/39401.htm
			// http://php.net/manual/zh/function.array-splice.php
			// 这里刷新数值键名是可以的，否则得用 unset！
			$key !== FALSE and array_splice($tags, $key, 1);
		}
		// 负向标签，正在审核中
		else if ($attitude == 'negative' && in_array('check_doing', $tags)) {
			$key = array_search('unchecked', $tags);
			$key !== FALSE and array_splice($tags, $key, 1);
		}
		
		return $tags;
	}
	
	
	
}
